<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>1.4. 全局块级绑定（Global Block Bindings）</title>
</head>
<body>

</body>
<script>
    ////////////////////////////////////1.4. 全局块级绑定（Global Block Bindings） START///////////////////////////
    /*
    let 与 const 另一处不同体现在全局作用域上。
    当在全局作用域内使用 var 声明时会创建一个全局变量，
    同时也是全局对象（浏览器环境下是 window）的一个属性。
    这意味着全局对象的属性可能会意外地被重写覆盖，例如：
    */
    // 在浏览器中运行
    //var RegExp = "Hello!";
    //console.log(window.RegExp);     // "Hello!"

    //var ncz = "Hi!";
    //console.log(window.ncz);        // "Hi!"
    /*
    虽然全局 RegExp 对象在 window 上已定义，但 var 声明很容易就能把它覆盖。
    这个例子就声明了一个新的 RegExp 变量并将原本的 RegExp 替换掉了。
    同样，ncz 也作为一个全局变量被声明并成为了 window 的属性。这就是 JavaScript 的工作机制。
     */
    console.group('------------------1.4. 全局块级绑定（Global Block Bindings）-----------------')
    /*
    如果你在全局作用域内使用 let 或 const，那么绑定就会发生在全局作用域内，
    但是不会向全局对象内部添加任何属性。
    这就意味着你不能使用 let 或 const 重写全局变量，
    而仅能屏蔽掉它们。如下所示
     */
    // 在浏览器中运行
    let RegExp = "Hello!";
    console.log(RegExp);                    // "Hello!"
    console.log(window.RegExp === RegExp);  // false

    const ncz = "Hi!";
    console.log(ncz);                       // "Hi!"
    console.log("ncz" in window);           // false
    /*
    在这里，let 声明创建了新的 RegExp 绑定并屏蔽掉了全局对象的 RegExp 属性。
    也就是说 window.RegExp 和 RegExp 并不等同，
    所以全局作用域并没有被污染。
    同样 const 声明创建了新的绑定的同时也没有在全局对象内部添加任何属性。
    这个设定使得在全局作用域内使用 let 或 const 声明要比 var 安全得多，
    特别是在你不想在全局对象内部添加属性的时候。
     */
    /**
     * 如果你想让代码可以被全局对象访问，你仍然需要使用 var，特别是当你想要在多个 window 和 frame 之间共享代码的时候
     * **/
    console.groupEnd();

    ////////////////////////////////////1.4. 全局块级绑定（Global Block Bindings） END///////////////////////////
</script>
</html>